﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MoonLight.LibCommon;
using MoonLight.LibSocket;
using PortScan.LibCommon;

namespace PortScan.Business
{
    class ScanProcess : Notifier
    {
        public ScanProcess(Notifier parent)
        {
            m_tcp = new AsynTcpSocket(this);
            m_parent = parent;
        }

        public void start_scan(object scan_info)
        {
            ProjectDefine.thread_info info = (ProjectDefine.thread_info)scan_info;
            int start = info.start_port;
            int end = info.end_port;
            string ip = info.ip;
            m_count = end - start + 1;
            Console.WriteLine("thread id [" + Thread.CurrentThread.ManagedThreadId + "] scan ports[" + start + "-" + end + "] of [" + ip + "]");
            for (int i = start; i <= end; i++)
            {
                if (m_tcp.CreateSocket() < 0)
                {
                    Console.WriteLine("create socket fail for port[" + i + "]");
                    continue;
                }
                m_tcp.Connect(ip, i);
            }
            //MessageInfo message = new MessageInfo(ProjectDefine.ProjectMsgType_e.MSG_THREAD_END);
            //m_parent.handle_message(message);
        }
        
        public override void handle_message(MessageInfo msg)
        {
            switch ((CommonDefine.MsgType_e)msg.msg_type)
            {
                case CommonDefine.MsgType_e.MSG_TCP_CONNECT:
                    {
                        if (msg.msg_data != null)
                        {
                            MessageInfo info = new MessageInfo(ProjectDefine.ProjectMsgType_e.MSG_PORT);
                            info.msg_data = msg.msg_data;
                            m_parent.handle_message(info);
                        }
                        m_count--;
                        if (m_count == 0) {
                            MessageInfo message = new MessageInfo(ProjectDefine.ProjectMsgType_e.MSG_THREAD_END);
                            m_parent.handle_message(message);
                        }
                    }
                    break;
                case CommonDefine.MsgType_e.MSG_TCP_ERR:
                    {
                        Logger.WriteLog("connect err, press any key to close client...");
                    }
                    break;
                default:
                    Logger.WriteLog("unknown msg type [" + msg.msg_type.ToString() + "]");
                    break;
            }
        }
        private int m_count;
        private AsynTcpSocket m_tcp;
        private Notifier m_parent;
    }
}
